home *** CD-ROM | disk | FTP | other *** search
/ The Very Best of Atari Inside / The Very Best of Atari Inside 1.iso / sharew / accs / drupatch / printer.c < prev    next >
Encoding:
C/C++ Source or Header  |  1985-07-21  |  7.1 KB  |  394 lines

  1. /*
  2.  *                    Drucker Accessory
  3.  *
  4.  *        - Druckeranpassung entsprechend PRINTER.DOT
  5.  *        - Druckvorgang geschieht im Hintergrund
  6.  *        - Druckparameter (Standardeinstellung in PRINTER.RSC)
  7.  *            Anzahl auszudruckender Zeilen pro Seite
  8.  *            Zeilenabstand n  (n/72 inch)
  9.  *            Tabulator
  10. */
  11.  
  12. #include <define.h>
  13. #include <gemdefs.h>
  14. #include <obdefs.h>
  15. #include "printer.h"
  16.  
  17. #define    byte    unsigned char
  18. #define    BUFLEN    16000
  19.  
  20. int        gl_apid;
  21.  
  22. int        menu_id;
  23. int        msg[8];            /* Ereignispuffer            */
  24. int        active;            /* Druck in Arbeit ?        */
  25. byte    *buffer;        /* Eingabepuffer            */
  26. long    buf_size;        /* Groesse des Puffers        */
  27. long    contents;        /* Inhalt des Puffers        */
  28. long    file_size;        /* restliche Dateilaenge    */
  29. int        fh;                /* File handle                */
  30. char    path[64];        /* Dateiname                */
  31.  
  32. int        line = 1;        /* aktuelle Druckzeile        */
  33. int        page;            /* Zeilen pro Seite            */
  34. int        spacing;        /* Zeilenabstand            */
  35. int        tabs;            /* Tabulator Einstellung    */
  36. int        final_ff;        /* Formfeed am Ende            */
  37.  
  38. char    *no_memory, *open_error, *interrupt;
  39. OBJECT    *form;
  40. char    *_line;
  41.  
  42. resources ()
  43. {
  44. no_memory  = "[2][Not enough memory available ... ][  Ok  ]";
  45. open_error = "[3][Can't open specified file ... ][ Cancel ]";
  46. interrupt  = "[1][The program is already active !][  Ok  | Cancel ]";
  47.  
  48.     if (!rsrc_load ("PRINTER.RSC")) {
  49.         page = 58;
  50.         spacing = 12;
  51.         tabs = 8;
  52.         return;
  53.     }
  54.     rsrc_gaddr (R_TREE, LAYOUT, &form);
  55.  
  56.     _line = ((TEDINFO*)(form+L_INF)->ob_spec)->te_ptext;
  57.     final_ff = (form+F_FF)->ob_state & CHECKED;
  58.  
  59.     page    = atoi (((TEDINFO*)(form+P_INF)->ob_spec)->te_ptext);
  60.     spacing    = atoi (((TEDINFO*)(form+S_INF)->ob_spec)->te_ptext);
  61.     tabs    = atoi (((TEDINFO*)(form+T_INF)->ob_spec)->te_ptext);
  62. }
  63.  
  64.  
  65. /*
  66.  *        Konvertierungstabelle einlesen
  67. */
  68.  
  69. int        *convert;        /* -> Tabelle von Zeigern auf code_table */
  70. byte    *code_table;    /* Ersetzungszeichen */
  71.  
  72. read_tab ()
  73. {
  74.     register int   fh;
  75.     register long  size;
  76.  
  77.     if ((fh = Fopen ("printer.dot", 0)) < 0)
  78.         return;
  79.     if (convert = (int*) Malloc (size = Fseek (0L, fh, 2))) {
  80.         code_table = (byte*)(convert + 256);
  81.         Fseek (0L, fh, 0);
  82.         Fread (fh, size, convert);
  83.     } else
  84.         form_alert (1, no_memory);
  85.     Fclose (fh);
  86. }
  87.  
  88. /*
  89.  *        H a u p t p r o g r a m m
  90. */
  91.  
  92. main ()
  93. {    
  94.     appl_init();
  95.     resources();
  96.     read_tab();
  97.     menu_id = menu_register (gl_apid, "  Print File");
  98.  
  99.     while (TRUE) {
  100.         evnt_mesag (msg);
  101.         if (msg[0] == AC_OPEN && msg[4] == menu_id)
  102.             read_file ();
  103.     }
  104. }
  105.  
  106.  
  107. /*
  108.  *        Auszudruckende Datei einlesen
  109. */
  110.  
  111. read_file ()
  112. {
  113.     if (! file_select (path, "*.*"))            /* Cancel ? */
  114.         return;
  115.     if ((fh = Fopen (path, 0)) < 0) {
  116.         form_alert (1, open_error);
  117.         return;
  118.     }
  119.     file_size = Fseek (0L, fh, 2);
  120.     buf_size = file_size < BUFLEN ? file_size : BUFLEN;
  121.  
  122.     while (!(buffer = (byte*) Malloc (buf_size)))
  123.         if ((buf_size = (long) Malloc (-1L)) < 200) {
  124.             form_alert (1, no_memory);
  125.             Fclose (fh);
  126.             return;
  127.         }
  128.     Fseek (0L, fh, 0);
  129.     contents = 0;            /* Puffer ist noch leer */
  130.     accessory();
  131.     Fclose (fh);
  132. }
  133.  
  134. /*
  135.  *        accessory
  136. */
  137.  
  138. accessory ()
  139. {
  140.     layout();
  141.  
  142.     if (active) {
  143.         out (0x1B); out ('A'); out (spacing);    /* Set line spacing */
  144.         out (0x1B); out ('2');
  145.  
  146.         print_file ();
  147.     }
  148.     Mfree (buffer);
  149. }
  150.  
  151.  
  152. /*
  153.  *        Objekt - Darstellung
  154. */
  155.  
  156. int  _x, _y, _w, _h;
  157.  
  158. center (tree)
  159. OBJECT  *tree;
  160. {
  161.     form_center (tree, &_x, &_y, &_w, &_h);
  162. }
  163.  
  164. dial (i)
  165. int  i;
  166. {
  167.     form_dial (i, 0,0,0,0, _x,_y,_w,_h);
  168. }
  169.  
  170. draw (tree, index)
  171. OBJECT  *tree;
  172. int  index;
  173. {
  174.     objc_draw (tree, index, 9, _x,_y,_w,_h);
  175. }
  176.  
  177. change (tree, index, state)
  178. OBJECT  *tree;
  179. int  index, state;
  180. {
  181.     objc_change (tree, index, 0, _x,_y,_w,_h, state, 1);
  182. }
  183.  
  184.  
  185. /*
  186.  *        Layout bestimmen
  187. */
  188.  
  189. layout ()
  190. {
  191.     register OBJECT    *obj;
  192.     register int  *value;
  193.     register int  index, n;
  194.     register int  exit = FALSE;
  195.  
  196.     n = active ? HIDETREE : SELECTABLE | EXIT;
  197.     active = TRUE;                    /* Druckjob wird gestartet */
  198.     if (!(obj = form))
  199.         return (FALSE);                /* kein Resource File vorhanden */
  200.  
  201.     itoa (line, _line);
  202.     (obj+L_LF)->ob_flags = n;
  203.     (obj+L_FF)->ob_flags = n;
  204.     center (obj);
  205.     wind_update (BEG_UPDATE);
  206.     dial (0);
  207.     draw (obj, 0);
  208.  
  209.     while (!exit) {
  210.         n = 1;
  211.         switch (index = form_do (obj, 0)) {
  212.             case CANCEL :
  213.                 active = FALSE;
  214.  
  215.             case PRINT :
  216.                 exit = TRUE;
  217.                 (obj+index)->ob_state = NORMAL;
  218.                 break;
  219.  
  220.             case L_LF :
  221.                 change (obj, L_LF, NORMAL);
  222.                 if (!Bcostat(0))
  223.                     break;
  224.                 if (line++ < page) {
  225.                     prt_char ('\r');
  226.                     prt_char ('\n');
  227.                     goto L_draw;
  228.                 }
  229.  
  230.             case L_FF :
  231.                 change (obj, L_FF, NORMAL);
  232.                 if (!Bcostat(0))
  233.                     break;
  234.                 line = 1;
  235.                 prt_char ('\f');
  236.             L_draw :
  237.                 itoa (line, _line);
  238.                 draw (obj, L_INF);
  239.                 break;
  240.  
  241.             case F_FF :
  242.                 (obj+F_FF)->ob_state = final_ff ^= CHECKED;
  243.                 draw (obj, F_FF);
  244.                 break;
  245.  
  246.             case P_DOWN :
  247.                 n = -1;
  248.             case P_UP :
  249.                 value = &page;
  250.                 index = P_INF;
  251.                 goto set_value;
  252.  
  253.             case S_DOWN :
  254.                 n = -1;
  255.             case S_UP :
  256.                 value = &spacing;
  257.                 index = S_INF;
  258.                 goto set_value;
  259.  
  260.             case T_DOWN :
  261.                 n = -1;
  262.             case T_UP :
  263.                 value = &tabs;
  264.                 index = T_INF;
  265.  
  266.             set_value :
  267.                 n += *value;
  268.                 if (n < 1 || n > 99)
  269.                     break;
  270.                 *value = n;
  271.                 itoa (n, ((TEDINFO*)(obj+index)->ob_spec)->te_ptext);
  272.                 draw (obj, index);
  273.                 break;
  274.         }
  275.     }
  276.  
  277.     dial (3);
  278.     wind_update (END_UPDATE);
  279.     return (TRUE);
  280. }
  281.  
  282. /*
  283.  *        In den Eingabepuffer einlesen
  284. */
  285.  
  286. read_buffer ()
  287. {
  288.     contents = buf_size < file_size ? buf_size : file_size;
  289.     Fread (fh, contents, buffer);
  290. }
  291.  
  292. /*
  293.  *        Datei ausdrucken
  294. */
  295.  
  296. print_file ()
  297. {
  298.     register byte  *s = buffer;
  299.     register int   next_tab = 0;
  300.     register int   c;
  301.  
  302.     while (active) {
  303.         if (--contents < 0) {                /* Puffer leer ? */
  304.             if (file_size <= 0)
  305.                 break;                        /* Datei ist leer */
  306.             read_buffer();
  307.             s = buffer;
  308.             continue;
  309.         }
  310.         c = *s++;                            /* Naechstes Zeichen */
  311.         file_size--;
  312.         if (--next_tab <= 0)
  313.             next_tab = tabs;
  314.         if (c == '\t') {                    /* Tabulator */
  315.             do
  316.                 prt_char (' ');
  317.             while (--next_tab > 0);
  318.             continue;
  319.         }
  320.         if (c == '\n') {                    /* Neue Zeile */
  321.             line++;
  322.             next_tab = 0;
  323.             if (line > page)
  324.                 c = '\f';
  325.         }
  326.         if (c == '\f') {                    /* Seitenvorschub */
  327.             line = 1;
  328.             next_tab = 0;
  329.         }
  330.         prt_char (c);
  331.     }
  332.     if (final_ff && active && c != '\f')
  333.         prt_char ('\f');
  334.     active = FALSE;
  335. }
  336.  
  337. /*
  338.  *        Ein Zeichen ausgeben (eventuell Konvertierung)
  339. */
  340.  
  341. prt_char (c)
  342. int  c;
  343. {
  344.     register byte  *code;
  345.     register int    k;
  346.  
  347.     if (!convert  ||  (k = convert[c]) < 0) {
  348.         out (c);                /* keine Konvertierung */
  349.         return;
  350.     }
  351.     code = code_table + k;
  352.     k = *code++;
  353.     while (--k > 0)
  354.         out (*code++);            /* Ausgabe der Ersatzzeichen */
  355. }
  356.  
  357. /*
  358.  *        Ein Byte ausdrucken 
  359. */
  360.  
  361. out (c)
  362. int  c;
  363. {
  364.     int  n = 0;
  365.  
  366.     while (active) {
  367.         if (Bcostat(0)) {        /* Drucker bereit */
  368.             Cprnout (c);
  369.             return;
  370.         }
  371.         if (n < 10)
  372.             n++;
  373.         else
  374.             pause ();
  375.     }
  376. }
  377.  
  378. /*
  379.  *        Pause einlegen
  380. */
  381.  
  382. pause ()
  383. {
  384.     int  event, ret;
  385.  
  386.     event = evnt_multi (MU_MESAG | MU_TIMER,
  387.                         0,0,0, 0,0,0,0,0, 0,0,0,0,0, msg, 0, 0,
  388.                         &ret, &ret, &ret, &ret, &ret, &ret);
  389.  
  390.     if (event & MU_MESAG  &&  msg[0] == AC_OPEN  &&  msg[4] == menu_id)
  391.         if (!layout()  &&  form_alert (1, interrupt) == 2)
  392.             active = FALSE;
  393. }
  394.